<?php
/**
 * Worker.php class file.
 * @author wudg <544038230@qq.com>
 * @date 2020/11/5- 10:40 上午
 */

namespace console\components\daemons\copy;

use common\exception\TaskException;
use console\components\helpers\ConsoleHelper;
use Swoole\Server;
use Yii;
use yii\helpers\FileHelper;

class Worker
{

    protected $server;

    protected $workerNumber = 2;

    protected $taskNum = 10;


    protected $processIdPath;


    public function __construct($daemon = false)
    {
        $this->processIdPath = Yii::getAlias(Yii::$app->params['daemon']['copy']['masterPidFilePath']);

        $this->server = new Server(Yii::$app->params['copy_task']['ip'],Yii::$app->params['copy_task']['port']);

        $setting =  [
            'worker_num' => Yii::$app->params['copy_task']['work_num'] ?? $this->workerNumber, //worker进程数
            'task_worker_num' =>Yii::$app->params['copy_task']['task_num'] ??  $this->taskNum, //task进程数
            'log_file' => $this->_createFilePath().'copy_task.log',
            'log_date_format' => '%Y-%m-%d %H:%M:%S', //日志时间格式
            'log_rotation' => 'SWOOLE_LOG_ROTATION_DAILY', //日志分割,按日期分割
        ];

        /**
         * 是否守护进程模式
         */
        if($daemon)
        {
            $setting['daemonize'] = 1;
        }

        $this->server->set($setting);

        $this->server->on("receive", [$this, 'onReceive']);
        $this->server->on("task", [$this, 'onTask']);
        $this->server->on("finish", [$this, 'onFinish']);
    }

    /**
     * 开启任务
     */
    public function run()
    {
        ConsoleHelper::runInfo('启动复制任务');

        /**
         * 返回当前服务的主进程id
         */
        file_put_contents($this->processIdPath, posix_getpid().PHP_EOL);
       $this->server->start();




    }

    /**
     * worker 进程回调
     * @param $serv
     * @param $fd
     * @param $from_id
     * @param $data
     * @throws \yii\db\Exception
     */
    public function onReceive($serv, $fd, $from_id, $data)
    {
        if(!Yii::$app->db->isActive)
        {
            Yii::$app->db->open();
        }
        //投递异步任务
        $task_id = $serv->task($data);
        ConsoleHelper::runInfo("投递任务成功，投递任务id:$task_id");

    }


    /**
     * task 进程回调
     * @param $serv
     * @param $task_id
     * @param $from_id
     * @param $data
     * @throws \common\exception\DriverException
     */
    public function onTask($serv, $task_id, $from_id, $data)
    {
        $dataArr = json_decode($data, true);
        ConsoleHelper::runInfo("任务接收到，将会在:".$dataArr['taskName'].'中执行');
        /**
         * 任务类型
         */
        if(!isset($dataArr['taskName']) || empty($dataArr['taskName'])) $serv->finish('taskName not find');
        try
        {
            (new Task($dataArr['taskName'],$dataArr['args']))->run();
        }catch(TaskException $e)
        {

            $serv->finish($e->getMessage());
        }


    }

    /**
     * 任务处理结束回调
     * @param $serv
     * @param $task_id
     * @param $data
     */
    public function onFinish($serv, $task_id, $data)
    {
        Yii::$app->db->close();
        ConsoleHelper::runInfo("复制task[$task_id] 执行完成：[$data]");
    }



    /**
     * 采集log目录初始化
     * @return bool|string
     * @throws \yii\base\Exception
     */
    protected function _createFilePath()
    {
        $path = Yii::getAlias('@runtime/task/copy/');

        //目录如果不存就先创建目录
        if(!is_dir($path)) {
            FileHelper::createDirectory($path);
        }

        return $path;
    }

}
